package com.aplink.dellcommercial.fragments;

import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;

import com.aplink.dellcommercial.R;
import com.aplink.dellcommercial.activities.FetchUserProfileActivity;
import com.aplink.dellcommercial.activities.MainActivity;
import com.aplink.dellcommercial.activities.ResetPasswordActivity;
import com.aplink.dellcommercial.configuration.DellController;
import com.aplink.dellcommercial.constant.FormDesignParameter.NewLogin;
import com.aplink.dellcommercial.database.DellDataTable;
import com.aplink.dellcommercial.util.DellCommercialUtility;
import com.aplink.dellcommercial.webservices.DataResult;
import com.aplink.dellcommercial.webservices.Methods;
import com.aplink.dellcommercial.webservices.WebServiceHelper;
import com.aplink.generic.GenericFragment;
import com.aplink.generic.constant.HandlerConstant;
import com.aplink.generic.constant.SqlDataType;
import com.aplink.generic.database.SqlMethods;
import com.aplink.generic.handler.IHandleMessage;
import com.aplink.generic.pojo.GenericAttribute;
import com.aplink.generic.pojo.GenericObject;
import com.aplink.generic.pojo.ObjPropInfo;
import com.aplink.generic.pojo.controlspec.ControlSpec;
import com.aplink.generic.util.convertcount.GenericConverter;
import com.aplink.generic.util.convertcount.GenericFilter;
import com.aplink.generic.util.validation.ControlValidation;

import java.util.ArrayList;

public class LoginFragment extends GenericFragment implements IHandleMessage {
    public static int intervalTimeMinute;
    private ArrayList<GenericAttribute<?, ?>> accountAttributes;
    public static int FETCH_USER_PROFILE_REQUEST_CODE = 1;
    public static int FETCH_USER_PROFILE_RESULT_CODE = 2;

    /**
     * 1. Call share preference to get Contact id.
     * <p/>
     * 2. Get user profile by contact id.
     */
    private void displayLoginProfile() {
        final String objectId = DellController.getInstance().getContactID();
        if ( objectId != null ) {
            String whereClause = SqlMethods.getInstance().equal( SqlDataType.INTEGER,
                    DellDataTable.UserLoginInfo.ACCOUNT_ID, objectId ).toString();
            final GenericObject genericObject = selectCommand().get(
                    getObjPropCol(), whereClause );
            if ( genericObject != null ) {
                this.setPassedGenericObject( genericObject );
            }
        }
    }

    private void handleDataResult( DataResult dataResult ) {
        if ( dataResult.getMethodName().equals( Methods.LOGIN ) ) {
            if ( dataResult.getData() != null ) {
                final GenericObject genericObject = (GenericObject) dataResult
                        .getData();
                genericObject.getAttributeList().addAll( this.accountAttributes );
                this.storeUserLoginInfo( genericObject );
                DellController.getInstance().setLogin( true );
            } else {
                DellCommercialUtility.showAlertDialog( getActivity(),
                        android.R.drawable.ic_dialog_alert, this.getResources()
                        .getString( R.string.error_login ), "Attention" );
            }
        }
    }

    private boolean offlineLogin( String username, String password ) {

        final String contactId = DellController.getInstance().getContactID();
        if ( contactId == null ) {
            Toast.makeText( getApplicationContext(),
                    "Please check your connection", Toast.LENGTH_SHORT ).show();
            return false;
        }
        final ArrayList<ObjPropInfo> userLoginInfo = getObjPropCol();
        String whereClause = SqlMethods.getInstance().equal( SqlDataType.INTEGER,
                DellDataTable.UserLoginInfo.CONTACT_ID, contactId ).toString();
        final GenericObject userInfo = selectCommand().get( getObjPropCol(),
                whereClause );

        final ObjPropInfo accountIdInfo = GenericFilter
                .getObjPropInfoOfAccountId( userLoginInfo );
        final ObjPropInfo accountPassInfo = GenericFilter
                .getObjPropInfoOfAccountPass( userLoginInfo );

        final String usernameDb = userInfo
                .getContentFromAttributeName( accountIdInfo.getObjectProperty() );
        final String passwordDb = userInfo
                .getContentFromAttributeName( accountPassInfo
                        .getObjectProperty() );

        if ( username.equalsIgnoreCase( usernameDb ) ) {
            if ( password.equals( passwordDb ) ) {
                DellCommercialUtility.setLocalTimeExpiry();
                DellController.getInstance().setLogin( true );
                return true;
            }
        }
        return false;
    }

    private void storeUserLoginInfo( GenericObject genericObject ) {
        long id = this.getDBHelper().insertOrUpdate( genericObject,
                this.getObjPropCol() );
        if ( id != - 1 ) {
            final Intent intent = new Intent( this.getApplicationContext(),
                    FetchUserProfileActivity.class );
            startActivityForResult( intent, FETCH_USER_PROFILE_REQUEST_CODE );
        }
    }

    @Override
    public void onActivityResult( int requestCode, int resultCode, Intent data ) {
        if ( requestCode == FETCH_USER_PROFILE_REQUEST_CODE
                && resultCode == FETCH_USER_PROFILE_RESULT_CODE ) {
            int result = data.getIntExtra( "FETCH_USER_RESULT",
                    FragmentActivity.RESULT_CANCELED );
            if ( result == FragmentActivity.RESULT_OK ) {
                Intent intent = new Intent( this.getApplicationContext(),
                        MainActivity.class );
                startActivity( intent );
                finishActivity();
            }
        }
    }

    private void submitLoginInformation() {
        this.accountAttributes = new ArrayList<GenericAttribute<?, ?>>();

        final ArrayList<ObjPropInfo> userLoginInfo = this.getObjPropList();

        final GenericObject userInfo = GenericConverter
                .convertObjPropValueIntoGenericObject( this.getObjPropValues(),
                        this.getTable(), userLoginInfo );

        final ObjPropInfo accountIdInfo = GenericFilter
                .getObjPropInfoOfAccountId( userLoginInfo );
        final ObjPropInfo accountPassInfo = GenericFilter
                .getObjPropInfoOfAccountPass( userLoginInfo );

        final String username = userInfo
                .getContentFromAttributeName( accountIdInfo.getObjectProperty() );
        final String password = userInfo
                .getContentFromAttributeName( accountPassInfo
                        .getObjectProperty() );

        if ( DellController.isOnline() ) {

            this.accountAttributes.add( new GenericAttribute<String, String>(
                    accountIdInfo.getObjectProperty(), username ) );
            this.accountAttributes.add( new GenericAttribute<String, String>(
                    accountPassInfo.getObjectProperty(), password ) );

            WebServiceHelper.getInstance().login( getActivity(),
                    this.getHandler(), username, password, userLoginInfo );
        } else {
            if ( this.offlineLogin( username, password ) ) {
                Intent intent = new Intent( getApplicationContext(),
                        MainActivity.class );
                startActivity( intent );
                this.finishActivity();
            } else {
                DellCommercialUtility.showAlertDialog( getActivity(),
                        android.R.drawable.ic_dialog_alert, this.getResources()
                        .getString( R.string.error_login ), "Attention" );
            }
        }
    }

    @Override
    public void onHandleControlClickEvent( ControlSpec controlSpec ) {
        final String validationGroup = controlSpec.getValidationGroup();
        if ( validationGroup.equalsIgnoreCase( NewLogin.VALIDATION_GROUP_LOGIN ) ) {
            if ( ControlValidation.isFormValidate( this, validationGroup ) ) {
                this.submitLoginInformation();
            }
        } else if ( validationGroup
                .equalsIgnoreCase( NewLogin.VALIDATION_GROUP_FORGET_PASSWORD ) ) {
            final Intent intent = new Intent( this.getApplicationContext(),
                    ResetPasswordActivity.class );
            this.startActivity( intent );
        }
    }

    @Override
    public void onActivityCreated( Bundle savedInstanceState ) {
        super.onActivityCreated( savedInstanceState );
        if ( DellController.getInstance().getLogin() ) {
            Intent intent = new Intent( getApplicationContext(),
                    MainActivity.class );
            startActivity( intent );
            finishActivity();
        } else {
            this.displayLoginProfile();
            try {
                intervalTimeMinute = Integer.parseInt( this.getResources()
                        .getString( R.string.intervalLoginTime ) );
            } catch ( final Exception e ) {
                intervalTimeMinute = 30;
            }
            this.initData();
            this.loadDataToForm();
            this.getHandler().setHandleMessage( this );
        }
    }

    @Override
    public void onHandleMessage( Message msg ) {
        if ( msg.what == HandlerConstant.HTTP_TASK_RESULT ) {
            final DataResult result = (DataResult) msg.obj;
            this.handleDataResult( result );
        }
    }

    @Override
    public int getContentView() {
        return R.layout.aplink_dellcommercial_login;
    }

    @Override
    public int getFormDesign() {
        return R.raw.form_design_new_login;
    }

    @Override
    public int getContentData() {
        return R.raw.content_data_new_login;
    }

    @Override
    public String getTable() {
        return DellDataTable.UserLoginInfo.TABLE_NAME;
    }

}
